/*
 * Copyright (c) 2016. For Intelligent Group.
 */

package com.intelligent.mts.da.handler;


import com.google.common.collect.Lists;
import com.intelligent.mts.common.utils.Identities;
import com.intelligent.mts.core.dto.ProductionDto;
import com.intelligent.mts.core.dto.SerialNumberDto;
import com.intelligent.mts.core.dto.TrackDto;
import com.intelligent.mts.core.service.DataSearchService;
import com.intelligent.mts.core.utils.AppConst;
import com.intelligent.mts.da.message.BaseDto;
import com.intelligent.mts.da.message.ProcessMessage;
import com.intelligent.mts.da.message.ReceiveMessage;
import com.intelligent.mts.da.utils.ApplicationBeanUtils;
import com.intelligent.mts.da.utils.MessageUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.AttributeKey;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * Created by Julia.Zhou on 2016/07/20.
 */
@Component
public class ValidateHandler extends ChannelInboundHandlerAdapter {

    public static Logger logger = LoggerFactory.getLogger(ValidateHandler.class);

    private DataSearchService dataSearchService;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        logger.info("Start validation process.");
        String returnMessage = "";
        ReceiveMessage receiveMessage = (ReceiveMessage) msg;
        String station = receiveMessage.getStationId();
        try {
            this.setService();
            AttributeKey<ReceiveMessage> attributeKey = null;
            if (!AttributeKey.exists(AppConst.VALIDATE_DATA)) {
                attributeKey = AttributeKey.newInstance(AppConst.VALIDATE_DATA);
            } else {
                attributeKey = AttributeKey.valueOf(AppConst.VALIDATE_DATA);
            }
            List<ProcessMessage> processMessageList = MessageUtils.getProcessMessage();
            String firstFlow = null;
            if (processMessageList != null && !processMessageList.isEmpty()) {
                firstFlow = processMessageList.get(0).getSid();
            }
            List<ProcessMessage> processSuMessageList = MessageUtils.getProcessSuMessage();
            String firstFlow1 = null;
            if (processSuMessageList != null && !processSuMessageList.isEmpty()) {
                firstFlow1 = processSuMessageList.get(0).getSid();
            }
            if (StringUtils.isBlank(firstFlow) || StringUtils.isBlank(firstFlow1)) {
                logger.info("First flow is empty.");
                returnMessage = AppConst.START_VALIDATE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
            } else {
                if (firstFlow.equals(receiveMessage.getStationId()) || firstFlow1.equals(receiveMessage.getStationId())) {
                    String result = this.saveFirstFlow(receiveMessage, ctx);
                    if (AppConst.RESULT_OK.equals(result)) {
                        ctx.channel().attr(attributeKey).set(receiveMessage);
                        returnMessage = AppConst.START_VALIDATE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_OK + AppConst.END_FLAG;

                    } else {
                        returnMessage = AppConst.START_VALIDATE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
                        logger.error("error");
                    }
                } else {
                    List<String> resultLists = this.saveSN(receiveMessage);
                    ctx.channel().attr(attributeKey).set(receiveMessage);
                    if (resultLists != null && !resultLists.isEmpty()) {
                        for (String result1 : resultLists) {
                            returnMessage += result1 + AppConst.SEPARATOR;
                        }
                        returnMessage = returnMessage.substring(0, returnMessage.length() - 1);
                        if (resultLists.size() == 1) {
                            returnMessage = resultLists.get(0);
                        }
                        returnMessage = AppConst.START_VALIDATE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + returnMessage + AppConst.END_FLAG;
                    } else {
                        returnMessage = AppConst.START_VALIDATE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + AppConst.RESULT_NG + AppConst.END_FLAG;
                        logger.error("resultlist is empty");
                    }
                }
            }

//            ctx.writeAndFlush(returnMessage);
            ctx.fireChannelRead(returnMessage);
            if (returnMessage.contains(AppConst.RESULT_NG)) {
                ctx.channel().attr(attributeKey).set(null);
            }
            logger.info("Process finish, return:[{}]", returnMessage);
        } catch (Exception e) {
            if (receiveMessage.getSnLists() != null && !receiveMessage.getSnLists().isEmpty()) {
                 for (String sn : receiveMessage.getSnLists().keySet()) {
                    returnMessage += AppConst.RESULT_NG + AppConst.SEPARATOR;
                }
                returnMessage = returnMessage.substring(0, returnMessage.length() - 1);
                if (receiveMessage.getSnLists().size() == 1) {
                    returnMessage =  AppConst.RESULT_NG;
                }

            }
            returnMessage = AppConst.START_VALIDATE_RESP + AppConst.SEPARATOR + station + AppConst.SEPARATOR + returnMessage + AppConst.END_FLAG;
//            ctx.writeAndFlush(returnMessage);
            ctx.fireChannelRead(returnMessage);
            logger.info("Process finish, return:[{}]", returnMessage);
            logger.error("Exception found:[{}]", e.getMessage());
            e.printStackTrace();
        }
     }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.warn("Unexpected exception from com.intelligent.mts.da.handler " + cause);
        ctx.fireExceptionCaught(cause);
    }

    private String saveFirstFlow(ReceiveMessage receiveMessage, ChannelHandlerContext ctx) {
        String result = null;
        String stationId = receiveMessage.getStationId();
        String pcba = receiveMessage.getPcba();
        String hou = receiveMessage.getHou();
        String pcbaPn = receiveMessage.getPcbaPn();
        String houPn = receiveMessage.getHouPn();
        String productId = null;

        if ((StringUtils.isNotBlank(pcba) && StringUtils.isNotBlank(hou))) {
            logger.error("Serialnumber count error.");
            return AppConst.RESULT_NG;
        }

        if ((StringUtils.isNotBlank(pcbaPn) && StringUtils.isNotBlank(houPn))) {
            logger.error("Product number count error.");
            return AppConst.RESULT_NG;
        }

        if (StringUtils.isNotBlank(pcba)) {
            if (MessageUtils.validateSnIsExistMoresProduction(pcba)) {
                return AppConst.RESULT_NG;
            }
            productId = dataSearchService.findProductionIdBySerialValue(pcba);
        } else if (StringUtils.isNotBlank(hou)) {
            if (MessageUtils.validateSnIsExistMoresProduction(hou)) {
                return AppConst.RESULT_NG;
            }
            productId = dataSearchService.findProductionIdBySerialValue(hou);
        } else {
            return AppConst.RESULT_NG;
        }

        if (StringUtils.isBlank(productId)) {
            String productionId = Identities.randomBase62(8);
            ProductionDto productionDto = new ProductionDto();
            productionDto.setProductionId(productionId);
            dataSearchService.createProduction(productionDto);

            SerialNumberDto serialNumberDto = new SerialNumberDto();
            serialNumberDto.setStationId(stationId);
            serialNumberDto.setProductionId(productionId);
            serialNumberDto.setSerialName(StringUtils.isBlank(pcba) ? AppConst.SN_HOU : AppConst.SN_PCBA);
            serialNumberDto.setSerialValue(StringUtils.isBlank(pcba) ? hou : pcba);
            serialNumberDto.setPnValue(StringUtils.isBlank(pcbaPn) ? houPn : pcbaPn);
            dataSearchService.createSerialNumber(serialNumberDto);
            receiveMessage.setProductionId(productionId);
            result = AppConst.RESULT_OK;
        } else {
            TrackDto trackDto = dataSearchService.findTrackByProductionId(productId);
            if (trackDto == null) {
                return  AppConst.RESULT_OK;
            }
            receiveMessage.setProductionId(productId);
            return MessageUtils.validateInProcess(stationId, trackDto);
        }
        return result;
    }

    public List<String> saveSN(ReceiveMessage receiveMessage) {
        String stationId = receiveMessage.getStationId();
       /* List<String> stations = Lists.newArrayList();
        List<BaseDto> returns = Lists.newArrayList();
        List<ProcessMessage> processMessageList = MessageUtils.getProcessMessage();
        if (processMessageList != null && !processMessageList.isEmpty()) {
            for (ProcessMessage processMessage : processMessageList) {
                if (processMessage.getReturns() != null && !processMessage.getReturns().isEmpty()) {
                    stations.add(processMessage.getSid());
                    returns.addAll(processMessage.getReturns());
                }
            }
        }

        List<ProcessMessage> processSuMessageList = MessageUtils.getProcessSuMessage();
        if (processSuMessageList != null && !processSuMessageList.isEmpty()) {
            for (ProcessMessage processMessage : processMessageList) {
                if (processMessage.getReturns() != null && !processMessage.getReturns().isEmpty()) {
                    stations.add(processMessage.getSid());
                    returns.addAll(processMessage.getReturns());
                }
            }
        }*/
        List<String> returnList = Lists.newArrayList();
        List<BaseDto> returns = Lists.newArrayList();
        List<String> output = Lists.newArrayList();

        if (AppConst.STATION_0930.equals(stationId)) {
            returnList = this.saveSnForStation0930(receiveMessage);
        } else if (AppConst.STATION_0690.equals(stationId)) {
            returnList = this.saveSnForStation0690(receiveMessage);
        } else if (AppConst.STATION_0620.equals(stationId)) {
            returnList = this.saveSnForTwoIn(receiveMessage);
        } else {
           returnList.add(this.saveSnForSigleIn(receiveMessage));
        }

        if (returnList.contains(AppConst.RESULT_NG)){
            return returnList;
        }
        List<ProcessMessage> processMessageList = MessageUtils.getProcessMessage();
        for(ProcessMessage processMessage : processMessageList)
        {
            if (receiveMessage.getStationId().equals(processMessage.getSid())){
                returns = processMessage.getReturns();
            }
        }
        List<ProcessMessage> processSuMessageList = MessageUtils.getProcessSuMessage();
        for(ProcessMessage processSuMessage : processSuMessageList)
            if (receiveMessage.getStationId().equals(processSuMessage.getSid())) {
                returns = processSuMessage.getReturns();
            }
        if (returns != null && returns.size() != 0 && !returns.isEmpty() && returnList.contains(AppConst.RESULT_OK)) {
            output = saveSnAndReturn(receiveMessage, returns);
        }
        for (String count :returnList) {
            output.add(AppConst.RESULT_OK);
        }
//        } else if (stations.contains(stationId)){
//            return this.saveSnAndReturn(receiveMessage, returns);
//      }
        return output;
    }

    private List<String> saveSnForStation0930(ReceiveMessage receiveMessage) {
        List<String> resultLists = Lists.newArrayList();
        String stationId = receiveMessage.getStationId();

        String hou = receiveMessage.getHou();
        String hs = receiveMessage.getHs();
        String houProductionId = null;
        String hsProductionId = null;
        String fgpn = null;
        if (StringUtils.isBlank(hs) && StringUtils.isBlank(hou)) {
            resultLists.add(AppConst.RESULT_NG);
            resultLists.add(AppConst.RESULT_NG);
            return resultLists;
        }

        if (StringUtils.isBlank(hs)) {
            resultLists.add(AppConst.RESULT_NG);
            logger.error("HS is empty.");
        }

        if (StringUtils.isBlank(hou)) {
            resultLists.add(AppConst.RESULT_NG);
            logger.error("HOU is empty.");
        }
//        String parentId = Identities.randomBase62(8);
        if (StringUtils.isNotBlank(hou) && StringUtils.isNotBlank(hs)) {
            if (MessageUtils.validateSnIsExistMoresProduction(hs)) {
                resultLists.add(AppConst.RESULT_NG);
                logger.error("HS repeated.");
            }

            if (MessageUtils.validateSnIsExistMoresProduction(hou)) {
                resultLists.add(AppConst.RESULT_NG);
                logger.error("HOU repeated.");
            }

            if (resultLists.contains(AppConst.RESULT_NG) && resultLists.size() > 1) {
                return resultLists;
            }
            TrackDto trackDto = null;
            if (!resultLists.contains(AppConst.RESULT_NG)) {
                hsProductionId = dataSearchService.findProductionIdBySerialValue(hs);
                if (StringUtils.isNotBlank(hsProductionId)) {
                    fgpn = dataSearchService.findFgPnByParentPrId(hsProductionId, AppConst.STATUS_ENABLE);
                    if (StringUtils.isBlank(fgpn)){
                        resultLists.add(AppConst.RESULT_NG);
                        resultLists.add(AppConst.RESULT_NG);
                        logger.error("fgpn is empty");
                        return resultLists;
                    }

                    trackDto = dataSearchService.findTrackByProductionId(hsProductionId);
                    if (trackDto != null) {
                        if (!stationId.equals(trackDto.getNextStation())) {
                            resultLists.add(MessageUtils.validateInProcess(stationId, trackDto));
                        } else {
                            if (StringUtils.isNotBlank(trackDto.getHs())) {
                                resultLists.add(trackDto.getHs());
                            } else {
                                resultLists.add(AppConst.RESULT_NG);
                                logger.error("HS status is empty.");
                            }
                        }
                    } else {
                        resultLists.add(AppConst.RESULT_NG);
                        logger.error("HS status is empty.");
                    }

                } else {
                    resultLists.add(AppConst.RESULT_NG);
                    logger.error("HS is not exist.");
                }

                houProductionId = dataSearchService.findProductionIdBySerialValue(hou);
                if (StringUtils.isNotBlank(houProductionId)) {
                    receiveMessage.setProductionId(hsProductionId);
                    trackDto = dataSearchService.findTrackByProductionId(houProductionId);
                    if (trackDto != null) {
                        if (!stationId.equals(trackDto.getNextStation())) {
                            resultLists.add(MessageUtils.validateInProcess(stationId, trackDto));
                        } else {
                            if (StringUtils.isNotBlank(trackDto.getHou())) {
                                resultLists.add(trackDto.getHou());
                            } else {
                                resultLists.add(AppConst.RESULT_NG);
                                logger.error("HOU status is empty.");
                            }
                        }
                    } else {
                        resultLists.add(AppConst.RESULT_NG);
                        logger.error("HOU status is empty.");
                    }
                } else {
                    logger.error("HOU is not exist.");
                    resultLists.add(AppConst.RESULT_NG);
                }
                return resultLists;
            }
        }
        TrackDto trackDto = null;
        if (StringUtils.isNotBlank(hs)) {
            hsProductionId = dataSearchService.findProductionIdBySerialValue(hs);
            if (StringUtils.isNotBlank(hsProductionId)) {
                trackDto = dataSearchService.findTrackByProductionId(hsProductionId);
                if (trackDto != null) {
                    if (!stationId.equals(trackDto.getNextStation())) {
                        resultLists.add(MessageUtils.validateInProcess(stationId, trackDto));
                    } else {
                        if (StringUtils.isNotBlank(trackDto.getHs())) {
                            resultLists.add(trackDto.getHs());
                        } else {
                            resultLists.add(AppConst.RESULT_NG);
                            logger.error("HS status is empty.");
                        }
                    }
                } else {
                    resultLists.add(AppConst.RESULT_NG);
                    logger.error("HS status is empty.");
                }
            } else {
                resultLists.add(AppConst.RESULT_NG);
                logger.error("HS is not exist.");
            }
        }

        if (StringUtils.isNotBlank(hou) && !resultLists.contains(AppConst.RESULT_NG)) {
            houProductionId = dataSearchService.findProductionIdBySerialValue(hou);
            if (StringUtils.isNotBlank(houProductionId)) {
                receiveMessage.setProductionId(hsProductionId);
                trackDto = dataSearchService.findTrackByProductionId(houProductionId);
                if (trackDto != null) {
                    if (!stationId.equals(trackDto.getNextStation())) {
                        resultLists.add(MessageUtils.validateInProcess(stationId, trackDto));
                    } else {
                        if (StringUtils.isNotBlank(trackDto.getHou())) {
                            resultLists.add(trackDto.getHou());
                        } else {
                            resultLists.add(AppConst.RESULT_NG);
                            logger.error("HOU status is empty.");
                        }
                    }
                } else {
                    resultLists.add(AppConst.RESULT_NG);
                    logger.error("HOU status is empty.");
                }
            } else {
                resultLists.add(AppConst.RESULT_NG);
                logger.error("HOU is not exist.");

            }
        }

        return resultLists;
    }

   private List<String> saveSnForStation0690(ReceiveMessage receiveMessage){
        List<String> resultLists = Lists.newArrayList();
        String stationId = receiveMessage.getStationId();
        String hs = receiveMessage.getHs();
        String productionId = null;
        String HsproductionId = null;

        if (StringUtils.isBlank(hs) || receiveMessage.getSnLists().size() > 1) {
            resultLists.add(AppConst.RESULT_NG);
            logger.error("Serialnumber error.");
            return resultLists;
        }

        if (MessageUtils.validateSnIsExistMoresProduction(hs)) {
            resultLists.add(AppConst.RESULT_NG);
            logger.error("HS repeated.");
            return resultLists;
        }
        productionId = dataSearchService.findProductionIdBySerialValue(hs);
       if (productionId.equals(AppConst.PRODUCTION_ID_0690)){
           resultLists.add(AppConst.RESULT_OK);
           return resultLists;
       }
        HsproductionId = dataSearchService.findHsProductionId(productionId);
        if (StringUtils.isBlank(productionId)) {
            resultLists.add(AppConst.RESULT_NG);
            logger.error("HS is not exist.");
            return resultLists;
        }
        receiveMessage.setProductionId(productionId);
        TrackDto trackDto = dataSearchService.findTrackByProductionId(productionId);
        if (trackDto != null) {
            if (!stationId.equals(trackDto.getNextStation()) && !trackDto.getStatus().equals(AppConst.RESULT_DEBUG)) {
                resultLists.add(MessageUtils.validateInProcess(stationId, trackDto));
                return resultLists;
            } else {
                if (StringUtils.isNotBlank(trackDto.getHs())) {
                    resultLists.add(trackDto.getHs());
                } else {
                    resultLists.add(AppConst.RESULT_NG);
                    logger.error("HS status is empty.");
                    return resultLists;
                }
            }

        } else {
            resultLists.add(AppConst.RESULT_NG);
            logger.error("HS status is empty.");
            return resultLists;
        }

        if (resultLists.contains(AppConst.RESULT_NG)) {
            return resultLists;
        } else {
            resultLists.clear();

            List<SerialNumberDto> serialNumberDtoList = dataSearchService.findSnByStationId(AppConst.STATION_0680, HsproductionId);
            if (serialNumberDtoList != null && !serialNumberDtoList.isEmpty()) {
                int successCount = 0;
                int gw_count =0;
                for (SerialNumberDto serialNumberDto : serialNumberDtoList) {
                    if (MessageUtils.validateSnIsExistMoresProduction(serialNumberDto.getSerialValue())) {
                        resultLists.add(AppConst.RESULT_NG);
                        logger.error("Serialnumber repeated, value:[{}]", serialNumberDto.getSerialValue());
                        return resultLists;
                    }
                    if (serialNumberDto.getSerialName().equals(AppConst.SN_GW)) {
                        gw_count = 1;
                    }
                    if (MessageUtils.getLinkSns() != null && !MessageUtils.getLinkSns().isEmpty()) {
                        for (String sn : MessageUtils.getLinkSns()) {
                            if (serialNumberDto.getSerialName().equals(sn)) {
                                successCount++;
                            }
                        }
                    }
                }

                if (gw_count != 1 ||  ( MessageUtils.getLinkSns() != null && successCount != MessageUtils.getLinkSns().size())){
                    resultLists.add(AppConst.RESULT_NG);
                    logger.error("0680 serialnumber matching error.", gw_count);
                    return resultLists;
                }
            } else {
                resultLists.add(AppConst.RESULT_NG);
                logger.error("0680 serialnumber id empty.");
                return resultLists;
            }
            String fgpn = dataSearchService.findFgPnByProductionId(HsproductionId);
            if (StringUtils.isBlank(fgpn)){
                resultLists.add(AppConst.RESULT_NG);
                logger.error("fgpn is empty");
                return resultLists;
            }
            if(!resultLists.contains(AppConst.RESULT_NG)) {
                resultLists.add(AppConst.RESULT_OK);
                dataSearchService.updateProductionFgPn(productionId, fgpn);
            }
            return resultLists;
        }
    }

    private String saveSnForSigleIn(ReceiveMessage receiveMessage) {
        String result = AppConst.RESULT_NG;
        String stationId = receiveMessage.getStationId();
        String productionId = null;

        if (receiveMessage.getSnLists() != null && !receiveMessage.getSnLists().isEmpty()) {
            for (String snName : receiveMessage.getSnLists().keySet()) {
                if (StringUtils.isNotBlank(receiveMessage.getSnLists().get(snName))) {
                    if (MessageUtils.validateSnIsExistMoresProduction(receiveMessage.getSnLists().get(snName))) {
                        logger.error("Serialnumber repeated, value:[{}]", receiveMessage.getSnLists().get(snName));
                        return result;
                    } else {
                        String firstSn = receiveMessage.getSnLists().get(snName);
                        productionId = dataSearchService.findProductionIdBySerialValue(firstSn);
                        if (StringUtils.isBlank(productionId)) {
                            logger.error("First serialnumber is not exist.");
                            return result;
                        }
                        receiveMessage.setProductionId(productionId);
                        TrackDto trackDto = dataSearchService.findTrackByProductionId(productionId);
                        if (trackDto == null) {
                            logger.error("First serialnumber status is empty.");
                            return result;
                        }
                        if (trackDto != null && !stationId.equals(trackDto.getNextStation())) {
                            if (MessageUtils.validateInProcess(stationId, trackDto).equals(AppConst.RESULT_OK)) {
                                receiveMessage.setProductionId(productionId);
                                return AppConst.RESULT_OK;
                            } else {
                                return result;
                            }
                        }

                        if (trackDto.getStatus().equals(AppConst.RESULT_NG)) {
                           return result;
                        } else {
                           return AppConst.RESULT_OK;
                        }
                    }
                }
            }
        }
        return result;
    }

    private List<String> saveSnForTwoIn(ReceiveMessage receiveMessage) {
        List<String> resultLists = Lists.newArrayList();
        String stationId = receiveMessage.getStationId();
        String hs = receiveMessage.getHs();
        String productionId = null;

        if (AppConst.STATION_0620.equals(stationId)) {
            if (receiveMessage.getSnLists() == null && receiveMessage.getSnLists().isEmpty()) {
                resultLists.add(AppConst.RESULT_NG);
                logger.error("0620 serialnumber count error.");
                return resultLists;
            }
            if (receiveMessage.getSnLists() != null && receiveMessage.getSnLists().size() != 2) {
                for (String snName1 : receiveMessage.getSnLists().keySet()) {
                    resultLists.add(AppConst.RESULT_NG);
                }
                logger.error("0620 serialnumber count error.");
                return resultLists;
            }
        }

        if (receiveMessage.getSnLists() != null && !receiveMessage.getSnLists().isEmpty()) {
            int i = 0;
            for (String snName : receiveMessage.getSnLists().keySet()) {
                if (StringUtils.isNotBlank(receiveMessage.getSnLists().get(snName))) {
                    if (MessageUtils.validateSnIsExistMoresProduction(receiveMessage.getSnLists().get(snName))) {
                        resultLists.add(AppConst.RESULT_NG);
                        logger.error("Serialnumber repeated, value:[{}]", receiveMessage.getSnLists().get(snName));
                        if (resultLists.size() == receiveMessage.getSnLists().keySet().size()) {
                            return resultLists;
                        }
                    } else {
                        if (i == 0) {
                            i++;
                            String firstSn = receiveMessage.getSnLists().get(snName);
                            productionId = dataSearchService.findProductionIdBySerialValue(firstSn);
                            if (StringUtils.isBlank(productionId)) {
                                for (String snName1 : receiveMessage.getSnLists().keySet()) {
                                    resultLists.add(AppConst.RESULT_NG);
                                }
                                logger.error("First serialnumber is not exist.");
                                return resultLists;
                            }
                            TrackDto trackDto = dataSearchService.findTrackByProductionId(productionId);
                            if (trackDto == null) {
                                for (String snName1 : receiveMessage.getSnLists().keySet()) {
                                    resultLists.add(AppConst.RESULT_NG);
                                }
                                logger.error("First serialnumber status is empty.");
                                return resultLists;
                            }
                            List<SerialNumberDto> serialNumberDtoList = dataSearchService.findSnListByProductionId(productionId);

                            //debug ok, or ok
                            if (trackDto != null && !stationId.equals(trackDto.getNextStation())) {
                                if (MessageUtils.validateInProcess(stationId, trackDto).equals(AppConst.RESULT_OK)) {
                                    receiveMessage.setProductionId(productionId);
                                    String productionId1 = dataSearchService.findProductionIdBySerialValue(receiveMessage.getSnLists().get(AppConst.SN_HS));
                                    if (StringUtils.isBlank(productionId1)) {
                                        for (String sn : receiveMessage.getSnLists().keySet()) {
                                            resultLists.add(AppConst.RESULT_OK);
                                        }
                                        return resultLists;
                                    }

                                    TrackDto trackDto1 = dataSearchService.findTrackByProductionId(productionId1);
                                    if (trackDto1 == null) {
                                        for (String sn : receiveMessage.getSnLists().keySet()) {
                                            resultLists.add(AppConst.RESULT_OK);
                                        }
                                        return resultLists;
                                    }

                                    if (AppConst.RESULT_DEBUG.equals(trackDto1.getStatus())) {
                                        for (String sn : receiveMessage.getSnLists().keySet()) {
                                            resultLists.add(AppConst.RESULT_OK);
                                        }
                                        return resultLists;
                                    }

                                    if (AppConst.RESULT_OK.equals(trackDto1.getStatus())) {
                                        if (!productionId.equals(productionId1)) {
                                            for (String sn : receiveMessage.getSnLists().keySet()) {
                                                resultLists.add(AppConst.RESULT_NG);
                                            }
                                        } else {
                                            for (String sn : receiveMessage.getSnLists().keySet()) {
                                                resultLists.add(AppConst.RESULT_OK);
                                            }
                                        }
                                        return resultLists;
                                    }

                                } else {
                                    for (String snName1 : receiveMessage.getSnLists().keySet()) {
                                        resultLists.add(AppConst.RESULT_NG);
                                    }
                                    return resultLists;
                                }
                            }

                            //normal
                            if (trackDto.getStatus().equals(AppConst.RESULT_NG)) {
                                if (serialNumberDtoList != null && !serialNumberDtoList.isEmpty()) {
                                    List<String> snList = Lists.newArrayList();
                                    for (SerialNumberDto serialNumberDto : serialNumberDtoList) {
                                        snList.add(serialNumberDto.getSerialValue());
                                    }
                                    for (String sn : receiveMessage.getSnLists().keySet()) {
                                        if (!snList.contains(receiveMessage.getSnLists().get(sn))) {
                                            resultLists.add(AppConst.RESULT_OK);
                                        } else {
                                            resultLists.add(AppConst.RESULT_NG);
                                        }
                                    }
                                }
                            } else {
                                if (serialNumberDtoList != null && !serialNumberDtoList.isEmpty()) {
                                    List<String> snList = Lists.newArrayList();
                                    for (SerialNumberDto serialNumberDto : serialNumberDtoList) {
                                        snList.add(serialNumberDto.getSerialValue());
                                    }
                                    for (String sn : receiveMessage.getSnLists().keySet()) {
                                        if (!snList.contains(receiveMessage.getSnLists().get(sn))) {
                                            String productionId1 = dataSearchService.findProductionIdBySerialValue(receiveMessage.getSnLists().get(sn));
                                            if (StringUtils.isNotBlank(productionId1) && !productionId.equals(productionId1) && !dataSearchService.findTrackByProductionId(productionId1).getStatus().equals(AppConst.RESULT_DEBUG)) {
                                                resultLists.add(AppConst.RESULT_NG);
                                            }else {
                                                resultLists.add(AppConst.RESULT_OK);
                                            }
                                        } else {
                                            String productionId1 = dataSearchService.findProductionIdBySerialValue(receiveMessage.getSnLists().get(sn));
                                            if (!productionId.equals(productionId1)) {
                                                resultLists.add(AppConst.RESULT_NG);
                                            } else {
                                                this.setResultList(trackDto, resultLists, sn);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        receiveMessage.setProductionId(productionId);

        return resultLists;
    }

    private List<String> saveSnAndReturn(ReceiveMessage receiveMessage, List<BaseDto> returns) {
        List<String> resultLists = Lists.newArrayList();
        String stationId = receiveMessage.getStationId();
        String productionId = null;
        String snKey = "";
        String snValue = "";
        String pnKey = "";
        String pnValue = "";
        for (String snvalue1 : receiveMessage.getSnLists().keySet()){
            switch (snvalue1){
                case AppConst.SN_HS:
                    productionId = dataSearchService.findProductionIdBySerialValue(receiveMessage.getHs());
                    break;
                case AppConst.SN_HOU:
                    productionId = dataSearchService.findProductionIdBySerialValue(receiveMessage.getHou());
                    break;
                case AppConst.SN_PCBA:
                    productionId = dataSearchService.findProductionIdBySerialValue(receiveMessage.getPcba());
                    break;
                default:
                    //resultLists.add(AppConst.RESULT_NG);
            }
        }
        for (BaseDto baseDto : returns) {
            if (baseDto.getValue().equals(AppConst.RETURN_VALUE_TYPE_SN)) {
                snKey = baseDto.getKey();
                snValue = receiveMessage.getSnLists().get(snKey);
                if (StringUtils.isBlank(snValue)){
                    SerialNumberDto serialNumberDto = dataSearchService.findCondition(productionId, receiveMessage.getStationId(), snKey);
                    if (serialNumberDto != null) {
                        snValue = serialNumberDto.getSerialValue();
                    }                }
                resultLists.add(snKey + "=" + snValue );
            } else if (baseDto.getValue().equals(AppConst.RETURN_VALUE_TYPE_PN)) {
                pnKey = baseDto.getKey();
                pnValue = receiveMessage.getPnLists().get(pnKey);
                if (StringUtils.isBlank(pnValue)){
                    pnValue = dataSearchService.findPnByParentPrIdAndKey(productionId, pnKey, AppConst.STATUS_ENABLE);
                }
                resultLists.add(pnKey + "=" + pnValue );
            } else if (baseDto.getValue().equals(AppConst.RETURN_VALUE_TYPE_SNPN)) {
                snKey = baseDto.getKey();
//                pnKey = baseDto.getKey();
                snValue = receiveMessage.getSnLists().get(snKey);
//                pnValue = receiveMessage.getPnLists().get(snKey);

                if (StringUtils.isBlank(snValue)){
                   SerialNumberDto serialNumberDto = dataSearchService.findCondition(productionId, receiveMessage.getStationId(), snKey);
                    if (serialNumberDto != null) {
                        snValue = serialNumberDto.getSerialValue();
//                        pnValue = serialNumberDto.getPnValue();
                    }
                }

                resultLists.add(snKey + "=" + snValue );
            }
        }
        return resultLists;
    }

    private void setResultList(TrackDto trackDto, List<String> resultLists, String snName) {
        if (trackDto != null) {
            if (snName.equals(AppConst.SN_PCBA)) {
                if (StringUtils.isNotBlank(trackDto.getPcba())) {
                    resultLists.add(trackDto.getPcba());
                } else {
                    resultLists.add(AppConst.RESULT_OK);
                }
            }

            if (snName.equals(AppConst.SN_HOU)) {
                if (StringUtils.isNotBlank(trackDto.getHou())) {
                    resultLists.add(trackDto.getHou());
                } else {
                    resultLists.add(AppConst.RESULT_OK);
                }
            }

            if (snName.equals(AppConst.SN_HS)) {
                if (StringUtils.isNotBlank(trackDto.getHs())) {
                    resultLists.add(trackDto.getHs());
                } else {
                    resultLists.add(AppConst.RESULT_OK);
                }
            }

            if (snName.equals(AppConst.SN_DSP_S)) {
                if (StringUtils.isNotBlank(trackDto.getDsp_s())) {
                    resultLists.add(trackDto.getDsp_s());
                } else {
                    resultLists.add(AppConst.RESULT_OK);
                }
            }

            if (snName.equals(AppConst.SN_DSP_P)) {
                if (StringUtils.isNotBlank(trackDto.getDsp_p())) {
                    resultLists.add(trackDto.getDsp_p());
                } else {
                    resultLists.add(AppConst.RESULT_OK);
                }
            }

            if (snName.equals(AppConst.SN_GW)) {
                if (StringUtils.isNotBlank(trackDto.getGw())) {
                    resultLists.add(trackDto.getGw());
                } else {
                    resultLists.add(AppConst.RESULT_OK);
                }
            }
        } else {
            resultLists.add(AppConst.RESULT_NG);
        }
    }

    public void setService() {
        if (dataSearchService == null) {
            dataSearchService = ApplicationBeanUtils.getBean(DataSearchService.class);
        }
    }
}